import pandas as pd
import tushare as ts
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
import __init__
import sys
import other
from get_data.tusharecopy.stock import wencaicopy
import numpy as np
import re
start_time, today_time, _hour_= other.time_start(dtype="with-")#start_time,today_time,today_hour=时间('20200731', '20200820', '16:12')
n_start_time, n_today_time, n_hour_= other.time_start(days=15,)
# print(start_time, today_time)
# other.funcat_time()
#————————————————————————————————————————————————————————————
"""
df1
当日数据get_today_ts()
df2
    df2
        历史数据get_his_data
        历史数据 for循环 getHisData_main
    df2fast
df3
当日数据get_today_data_else()
3.1 及时数据处理 


"""
#df1————————————————————————————————————————————————————————————
@other.time_
def get_today_ts():
    try:
        csv_data = ts.get_today_all()  # 读取today实时数据
        csv_data["liutongliang"] = csv_data["nmc"] / csv_data["trade"]
        csv_data.to_csv("db_temp/1.数据下载.txt", encoding="utf-8")
        print("保存数据到db_temp/1.数据下载.txt中,获取{}项".format(len(csv_data)))

    except:
        print("从db_temp/1.数据下载.txt中，读取数据")
        csv_data = pd.read_csv("db_temp/1.数据下载.txt", index_col=0)
    csv_data=other.re_read_df(csv_data)
    # else:
    #     csv_data=get_today_data_else()
    return csv_data
#df2————————————————————————————————————————————————————————————
def get_his_data(code='600848',num=3,start=start_time, end=today_time):
    """

    p_change：涨跌幅
ma5：5日均价
ma10：10日均价
ma20:20日均价
v_ma5:5日均量
v_ma10:10日均量
v_ma20:20日均量
turnover:换手率[注：指数无此项]
                 high    low  close    volume
date
2021-11-09  14.30  14.18  14.23  21198.71
2021-11-08  14.27  14.16  14.24  23478.14
('600848', 14.3, 14.18, 14.23, 21198.71, 14.27, 14.16, 14.24, 23478.14)
#('600848', 2021-11-09 , 2021-11-08 )
    :param code:
    :return:
    """
    other._write_console()
    df=ts.get_hist_data(code,start=start,end=end)  # 一次性获取全部日k线数据
    #print(df)
    try:
        if len(df)==0:
            return ()
        df=df[["high","low","close","volume"]][:num]
        #print(df)
        df = df.apply(lambda x: tuple(x), axis=1).values.tolist()
        stock_tuple=(code,)+df[0]+df[1]+df[2]
        #print(stock_tuple)
        if len(stock_tuple)==4*num+1:
            return stock_tuple
        else:
            #对应none数据
            return ()
    except:
        return ()
@other.time_
def getHisData_main():
    """
    从db_temp/1.数据下载.txt获取数据->stock_list
    for循环i_stock
        可视化进度条
    +时间
    +保存

    >>>结果返回今天及前2天数据
    ,code,h_,l_,c_,v_,h_1,l_1,c_1,v_1,h_2,l_2,c_2,v_2,time
0,688981,54.89,54.3,54.71,223466.41,55.33,54.52,54.57,237462.19,55.71,54.61,55.26,231262.47,20211119
1,688819,48.28,45.11,47.74,77913.51,46.5,44.5,45.66,65665.07,44.56,42.82,44.44,38836.96,20211119
    975秒，约16分钟。
    :return:
    """
    stock_list=other.stock_all_list(path_="db_temp/1.数据下载.txt")[:]#["002274","300789"]
    _stock_df=[]
    i=0
    for i_stock in stock_list:
        stock_tuple=get_his_data(code=i_stock)
        _stock_df.append(stock_tuple)
        #可视化
        i+=1
        other.progress_bar(i)
    stock_df=pd.DataFrame(_stock_df,columns=['code','h_','l_','c_','v_','h_1','l_1','c_1','v_1','h_2','l_2','c_2','v_2'])
    stock_df["time"]=other.funcat_time()[0]
    # print(stock_df)
    stock_df.to_csv("db_temp/2.his数据下载.txt", encoding="utf-8")
    return stock_df

@other.time_
def get_his_data_fast(start_date=n_start_time, end_date=n_today_time):
    """
    >>>作为getHisData_main fast版本,多股票运行,效率更快,约20秒.
     从pro.stock_basic(->len_data
     for循环len_data
        [000001.SZ,000002.SZ,000004.SZ,000005.SZ,000006.SZ,000007.SZ,000008.SZ...]
        list变为str
         pro.daily(ts_code=

     +保存

     >>>结果返回今天及前2天数据
     """
    pro = ts.pro_api()
    df = pro.stock_basic(exchange='', list_status='L', fields='')
    len_data = int(len(df) / 100 + 1)
    temp = pd.DataFrame()

    for i in range(len_data):
        ts_get_datalist = df[100 * i:100 * (i + 1)].ts_code.tolist()
        #print(",".join(ts_get_datalist))
        test_list = ",".join(ts_get_datalist)

        # 多个股票
        #   df = pro.daily(ts_code='000001.SZ,600000.SH', start_date='20180701', end_date='20180718')
        _df = pro.daily(ts_code=test_list, start_date=n_start_time, end_date=n_today_time)
        temp = pd.concat([temp, _df])
    temp.to_csv("db_temp/2.his数据下载_fast1.txt", encoding="utf-8")

    temp=_df_handle_method(temp)
    temp.to_csv("db_temp/2.his数据下载_fast.txt", encoding="utf-8")
    return temp

def _df_handle_method(df):
    n = list(set(df.trade_date))
    # 用sort将列表进行排序，reverse=True为降序设置
    n.sort(reverse=True)
    if len(n) > 2:
        print(df[df.trade_date == n[0]])
        df_1 = df[df.trade_date == n[0]][['ts_code', "high", "low", "close", "vol"]]
        df_2 = df[df.trade_date == n[1]][['ts_code', "high", "low", "close", "vol"]]
        df_3 = df[df.trade_date == n[2]][['ts_code', "high", "low", "close", "vol"]]
        _df = pd.merge(df_1, df_2, how='inner', on='ts_code')
        _df = pd.merge(_df, df_3, how='inner', on='ts_code')

        _df.rename(
            columns={'ts_code': "code", "high_x": "h_", "low_x": "l_", "close_x": "c_", "vol_x": "v_", "high_y": "h_1",
                     "low_y": "l_1", "close_y": "c_1", "vol_y": "v_1", "high": "h_2", "low": "l_2", "close": "c_2",
                     "vol": "v_2"}, inplace=True)
        _df = pd.concat([_df[['h_', 'l_', 'c_', 'v_', 'h_1', 'l_1', 'c_1', 'v_1', 'h_2', 'l_2', 'c_2', 'v_2']],
                         _df.code.str.split('.', expand=True).rename(columns={0: 'code', 1: 'sz代码'})],
                        axis=1)  # 将000001.SZ 进行列拆分
        del _df['sz代码']
        _df["time"]=n[0]
        _df=pd.DataFrame(_df,columns=["code",'h_','l_','c_','v_','h_1','l_1','c_1','v_1','h_2','l_2','c_2','v_2',"time"])
        return _df

    else:
        raise ("列表日期少于3天")
#df3————————————————————————————————————————————————————————————
@other.time_
def get_today_data_else():
    """
    时常3s
    1.读取股票dataframe（补全）
    2.for循环code
    :return:
    """
    df = pd.read_csv("db_temp/1.数据下载.txt", encoding="utf-8", index_col=0)
    df=other.re_read_df(df)
    len_data = int(len(df) / 450 + 1)
    temp = pd.DataFrame()

    for i in range(len_data):
        ts_get_datalist = df[450 * i:450 * (i + 1)].code.tolist()
        _df = ts.get_realtime_quotes(ts_get_datalist)  # Single stock symbol
        _df = _df[['code', 'open', 'price', 'low', 'high', 'pre_close', 'volume', 'time']]

        temp = pd.concat([temp, _df])

    ts_get_data = temp.reset_index(drop=True)  # 重建索引
    # obj格式变成float
    ts_get_data['open'] = pd.to_numeric(ts_get_data['open'])
    ts_get_data['low'] = pd.to_numeric(ts_get_data['low'])
    ts_get_data['trade'] = pd.to_numeric(ts_get_data['price'])
    ts_get_data['high'] = pd.to_numeric(ts_get_data['high'])
    ts_get_data['volume'] = pd.to_numeric(ts_get_data['volume'])
    ts_get_data['settlement'] = pd.to_numeric(ts_get_data['pre_close'])
    #print("df_3", ts_get_data)
    ts_get_data.to_csv("db_temp/1.1.数据备份快速下载.txt", encoding="utf-8")
    return ts_get_data
def df2Mergedf1():
    """
    1.读取历史股票df_2
     1.1逻辑：
        if 时间相等：
            if周六：
                2.his数据下载
            else:非周六
                3.数据+2.his数据下载
        else:
            重新运行2.his数据下载
            df=重新运行程序
            return df

    """
    df_2 = other.stock_all_list(path_="db_temp/2.his数据下载.txt", dtype="2.1")
    a1=(other.time_zhou6_0(dtype="df").pretrade_date[-1:]).item()
    a2=df_2.time[0].astype(str)
    if (a1)==(a2):  # 日期相等
        if int(other.time_zhou6_0(dtype="df")[-1:].is_open) == 0:  # 周六
            df_2.to_csv("db_temp/3.1数据.txt", encoding="utf-8",index=False)
            print("保存数据到db_temp/3.1数据.txt中,获取{}项".format(len(df_2)))
            return df_2
        else:#平时
            dtype="2"
            if  dtype=="1":
                df_3=get_today_data_else()
                _df = pd.merge(df_2, df_3, how='inner', on='code')
            else:
                df_1=get_today_ts()
                _df=pd.merge(df_2, df_1, how='inner', on='code')
                _df = _method_mm(_df)#数据整理
            _df.to_csv("db_temp/3.1数据.txt", encoding="utf-8")

            return _df
    else:
        print("日期不等,重新获取数据,重新运行df_2")
        stock_df=get_his_data_fast()#代替，从30分钟降到15秒->getHisData_main()
        stock_df.to_csv("db_temp/2.his数据下载.txt", encoding="utf-8")
        _df=df2Mergedf1()
        return _df
def _method_mm(df):
    df["pre_close"] = df["settlement"]
    df["price"] = df["trade"]
    df["time_y"] = ""
    df = df[["code", 'h_', 'l_', 'c_', 'v_', 'h_1', 'l_1', 'c_1', 'v_1', 'h_2', 'l_2', 'c_2', 'v_2', "time",
             "open", "price", "low", "high", "pre_close", "volume", "time_y", "trade", "settlement",
             "turnoverratio", "amount", "per", "pb", "mktcap", "nmc", "liutongliang"]]
    return df
#di1————————————————————————————————————————————————————————————
def DMI_method_60(df:pd.DataFrame=""):#周六
    df = df2Mergedf1()
    df = df.loc[:, ~df.columns.str.contains('^Unnamed')].drop_duplicates()  # 2去掉Unnamed 并且去重
    # 1.1 TR
    # df=df.set_index('code',drop=False)
    a = np.array(df)
    #print(a.shape)
    # ['code','h_','l_','c_','v_','h_1','l_1','c_1','v_1','h_2','l_2','c_2','v_2'])
    # a=a[:,1]-a[:,2]
    a1 = (a[:, 1] - a[:, 2])
    a2 = abs(a[:, 1] - a[:, 7])
    a3 = np.max([a1, a2], axis=0)
    a4 = abs(a[:, 2] - a[:, 7])
    a5 = np.max([a3, a4], axis=0)

    a6 = (a[:, 5] - a[:, 6])
    a7 = abs(a[:, 5] - a[:, 11])
    a8 = np.max([a6, a7], axis=0)
    a9 = abs(a[:, 6] - a[:, 11])
    a10 = np.max([a8, a9], axis=0)
    #print(a5.shape , a10.shape)
    tr = a5 + a10
    # 1.2 HD
    hd1 = (a[:, 1] - a[:, 5])
    ld1 = (a[:, 6] - a[:, 2])
    # 1.3 DMP
    # 假设我们想要根据cond中的值选取xarr和yarr的值：当cond中的值为true时，选取xarr的值，否则从yarr中选取。列表推导式的写法应该如下所示：
    # xarr = np.array([1.1,1.2,1.3,1.4,1.5])
    # yarr = np.array([2.1,2.2,2.3,2.4,2.5])
    # cond = np.array([True,False,True,True,False])
    # result = [(x if c else y) for x, y, c in zip(xarr, yarr, cond)]
    # print(result)
    cond1 = (hd1 > 0) & (hd1 > ld1)
    xarr1 = hd1
    yarr1 = np.zeros((len(xarr1),), dtype=int)
    result1 = [(x if c else y) for x, y, c in zip(xarr1, yarr1, cond1)]
    dmp1 = np.array(result1)

    hd2 = (a[:, 5] - a[:, 9])
    ld2 = (a[:, 10] - a[:, 6])
    cond2 = (hd2 > 0) & (hd2 > ld2)
    xarr2 = hd2
    yarr2 = np.zeros((len(xarr2),), dtype=int)
    result2 = [(x if c else y) for x, y, c in zip(xarr2, yarr2, cond2)]
    dmp2 = np.array(result2)

    dmp = dmp1 + dmp2
    df["di1"] = dmp/tr * 100

    print(len(df[df.di1>45]))
    df_=df[(df.h_>df.h_2)&(df.di1>45)]
    df_.to_csv("db_temp/3.2数据di1.txt", encoding="utf-8")
    print("及时数据，包含停牌股票",df_)
def DMI_method_61(df=""):#平时
    df =df2Mergedf1()
    df = df.loc[:, ~df.columns.str.contains('^Unnamed')].drop_duplicates()  # 2去掉Unnamed 并且去重
    # df_3 =ts_his.get_today_data_else()
    # df = pd.merge(df, df_3, how='inner', on='code')
    #
    # df.to_csv("db_temp/3.1数据.txt", encoding="utf-8")
    # 1.1 TR
    # df=df.set_index('code',drop=False)
    a = np.array(df)
    #print(a.shape)
    # ['code','h_','l_','c_','v_','h_1','l_1','c_1','v_1','h_2','l_2','c_2','v_2'])
    # a=a[:,1]-a[:,2]
    a1 = (a[:, 1] - a[:, 2])
    a2 = abs(a[:, 1] - a[:, 7])
    a3 = np.max([a1, a2], axis=0)
    a4 = abs(a[:, 2] - a[:, 7])
    a5 = np.max([a3, a4], axis=0)
    """
    DMI_method_60代码成熟，采用a1-a5不变，a6-a10修改
    """
    a6 = (a[:, 17] - a[:, 16])
    a7 = abs(a[:, 17] - a[:, 22])
    a8 = np.max([a6, a7], axis=0)
    a9 = abs(a[:, 16] - a[:, 22])
    a10 = np.max([a8, a9], axis=0)
    #print(a5.shape , a10.shape)
    tr = a5 + a10
    # 1.2 HD
    hd1 = (a[:, 1] - a[:, 5])
    ld1 = (a[:, 6] - a[:, 2])
    # 1.3 DMP
    # 假设我们想要根据cond中的值选取xarr和yarr的值：当cond中的值为true时，选取xarr的值，否则从yarr中选取。列表推导式的写法应该如下所示：
    # xarr = np.array([1.1,1.2,1.3,1.4,1.5])
    # yarr = np.array([2.1,2.2,2.3,2.4,2.5])
    # cond = np.array([True,False,True,True,False])
    # result = [(x if c else y) for x, y, c in zip(xarr, yarr, cond)]
    # print(result)
    cond1 = (hd1 > 0) & (hd1 > ld1)
    xarr1 = hd1
    yarr1 = np.zeros((len(xarr1),), dtype=int)
    result1 = [(x if c else y) for x, y, c in zip(xarr1, yarr1, cond1)]
    dmp1 = np.array(result1)
    """
    DMI_method_60代码成熟，采用hd1不变，hd2修改
    """
    hd2 = (a[:, 17] - a[:, 1])
    ld2 = (a[:, 2] - a[:, 16])
    cond2 = (hd2 > 0) & (hd2 > ld2)
    xarr2 = hd2
    yarr2 = np.zeros((len(xarr2),), dtype=int)
    result2 = [(x if c else y) for x, y, c in zip(xarr2, yarr2, cond2)]
    dmp2 = np.array(result2)

    dmp = dmp1 + dmp2
    df["di1"] = dmp/tr * 100

    # print(len(df[df.di1>45]))
    # df_=df[(df.h_>df.h_2)&(df.di1>45)]
    df_=df
    df_.sort_values(by="turnoverratio", ascending=False)
    df_.to_csv("db_temp/3.2数据di1.txt", encoding="utf-8")
    print("及时数据，包含停牌股票",len(df_))
    return df_
# def DMI_1(M1=2, M2=1):
#     """
#     DMI 趋向指标
#     """
#     TR = SUM(MAX(MAX(HIGH - LOW, ABS(HIGH - REF(CLOSE, 1))), ABS(LOW - REF(CLOSE, 1))), M1)
#     HD = HIGH - REF(HIGH, 1)
#     LD = REF(LOW, 1) - LOW
#
#     DMP = SUM(IF((HD > 0) & (HD > LD), HD, 0), M1)
#     DMM = SUM(IF((LD > 0) & (LD > HD), LD, 0), M1)
#     DI1 = DMP * 100 / TR
#     DI2 = DMM * 100 / TR
#     ADX = MA(ABS(DI2 - DI1) / (DI1 + DI2) * 100, M2)
#     ADXR = (ADX + REF(ADX, M2)) / 2
#v_ma_5————————————————————————————————————————————————————————————
def his_fast1_mdTOma5():
    df= pd.read_csv("db_temp/2.his数据下载_fast1.txt", index_col=0)
    n = list(set(df.trade_date))
    # 用sort将列表进行排序，reverse=True为降序设置
    n.sort(reverse=True)
    if len(n) >= 5:
        temp = df[df.trade_date == n[0]][['ts_code', "high", "low", "close", "vol"]]
        for i in range(1, 5):
            _df = df[df.trade_date == n[i]][['ts_code', "high", "low", "close", "vol"]]
            temp = pd.merge(temp, _df, how='inner', on='ts_code')
    #计算v_ma_5
    temp.columns = [i for i in range(21)]
    a = np.array(temp)
    a_v_total = a[:, 4] + a[:, 8] + a[:, 12] + a[:, 16] + a[:, 20]
    a_v_ma5 = a_v_total / 5
    temp["v_ma5"] = a_v_ma5
    temp= pd.concat([temp["v_ma5"],temp[0].str.split('.', expand=True).rename(columns={0: 'code', 1: 'sz代码'})],axis=1)  # 将000001.SZ 进行列拆分

    temp.to_csv("db_temp/2.his数据下载_fast1_1.txt", encoding="utf-8")
    return temp[["code","v_ma5"]]
def DmiWith_V_ma5():
    df_dmi1=DMI_method_61()
    df_v_ma5=his_fast1_mdTOma5()
    _df=pd.merge(df_dmi1, df_v_ma5, how='inner', on='code')
    _df.to_csv("db_temp/3.4数据di1&v_ma5.txt", encoding="utf-8")
    return _df
if __name__ == '__main__':
    # get_today_data_else()
    # get_his_data_fast()
    DmiWith_V_ma5()
